package com.hksj.common.core.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * @author fjt
 * @date： 2023/11/8 17:13
 * @description：时间工具类
 */
public class DateUtil {

    public static final String DEFAULT_FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_FORMAT = "yyyyMMddHHmmss";
    public static final String DEFAULT_FORMAT_Hour = "yyyy-MM-dd HH";
    public static final String DEFAULT_FORMAT_DATE = "yyyy-MM-dd";
    public static final String FORMAT_DATE = "yyyyMMdd";
    public static final String DEFAULT_FORMAT_MONTH = "yyyy-MM";
    public static final String DEFAULT_FORMAT_TIME = "HH:mm:ss";
    public static final String DEFAULT_FORMAT_YEAR_MONTH_DATE = "yyMMdd";


    /**
     * 获取指定日期的前几天(负数)/后几天
     * @param appointDate
     * @param num
     * @param datePatten
     * @return
     */
    public static String getAfterDate(String appointDate, int num, String datePatten){
        Calendar calendar = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat(datePatten).parse(appointDate);
        }
        catch (ParseException e) {
            e.printStackTrace();
        }
        calendar.setTime(date);
        calendar.add(Calendar.DATE, num);

        String appointDay = new SimpleDateFormat(datePatten).format(calendar.getTime());
        return appointDay;
    }


    /**
     * 将指定格式的字符串形式的时间解析成LocalDateTime
     * @param formatDate
     * @param pattern
     * @return LocalDateTime
     */
    public static LocalDateTime parseFormatDate(String formatDate, String pattern) {
        return LocalDateTime.parse(formatDate, getFormatter(pattern));
    }

    /**
     * 获取指定格式的时间字符串
     * @param localDate
     * @param pattern
     * @return 当前时间
     */
    public static String getFormatDate(LocalDate localDate, String pattern) {
        return localDate.format(getFormatter(pattern));
    }


    public static String getFormatDate(LocalDateTime localDateTime, String pattern){
        return localDateTime.format(getFormatter(pattern));
    }

    /**
     * 获取当前时间
     * @return
     */
    public static Date getNow(){
        LocalDateTime localDateTime = LocalDateTime.now();
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }


    /**
     * 获取指定时间的前一天
     * @param date
     * @return
     */
    public static Date getYesterday(Date date){
        LocalDateTime time = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusDays(1);
        return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取指定时间的上个月
     * @param date
     * @return
     */
    public static Date getLastMonth(Date date){
        LocalDateTime time = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusMonths(1);
        return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取指定时间的前一年
     * @param date
     * @return
     */
    public static Date getLastYear(Date date){
        LocalDateTime time = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusYears(1);
        return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取当前时间所在月份
     * @return
     */
    public static int getMonth(){
        return LocalDate.now().getMonthValue();
    }


    /**
     * 获取当前时间所在月份的第一天
     * @return
     */
    public static Date getFirstDayOfMonth(){
        LocalDate localDate = LocalDate.now().withDayOfMonth(1);
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取当前时间所在年份的第一天
     * @return
     */
    public static Date getFirstDayOfYear(){
        LocalDate localDate = LocalDate.now().withDayOfYear(1);
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取当前时间所在周的第一天
     * @return
     */
    public static Date getFirstDayOfWeek(){
        LocalDate localDate = LocalDate.now().with(DayOfWeek.MONDAY);
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取指定时间所在月份的最后一天
     * @param date
     * @return
     */
    public static LocalDate getLastDayOfReportingPeriod(Date date){
        LocalDate localDate = convertToLocalDate(date);
        return localDate.with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 获取指定时间所在年份的最后一天
     * @param date
     * @return
     */
    public static LocalDate getLastDayOfYearToWhichBelongs(Date date){
        LocalDate localDate = convertToLocalDate(date);
        return localDate.with(TemporalAdjusters.lastDayOfYear());
    }


    /**
     * 获取指定时间段内的每一天
     * @param start
     * @param end
     * @return
     */
    public static List<LocalDate> getDatesInRange(LocalDate start, LocalDate end) {
        List<LocalDate> dates = new ArrayList<>();
        LocalDate currentDate = start;

        while (!currentDate.isAfter(end)) {
            dates.add(currentDate);
            currentDate = currentDate.plusDays(1);
        }
        return dates;
    }

    /**
     * 获取指定时间段内的每月第一天
     * @param start
     * @param end
     * @return
     */
    public static List<LocalDate> getEveryMonthInRange(LocalDate start, LocalDate end){
        List<LocalDate> monthlyDates = new ArrayList<>();
        // 循环添加每个月的第一天
        while (start.isBefore(end) || start.isEqual(end)) {
            // 添加每个月的第一天
            monthlyDates.add(start.withDayOfMonth(1));
            // 前进到下一个月
            start = start.plusMonths(1);
        }
        return monthlyDates;
    }


    /**
     * 将 Date 转换为 LocalDate
     * @param date
     * @return
     */
    public static LocalDate convertToLocalDate(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * 把LocalDate转为Date
     * @param localDate
     * @return
     */
    public static Date convertToDate(LocalDate localDate){
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    public static Date convertToDate(LocalDateTime localDateTime){
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取明天零点整到当前时间的时间差，单位：秒
     * @return
     */
    public static long getExpireTime(){
        Calendar cal = Calendar.getInstance();// 今天日终
        cal.add(Calendar.DAY_OF_YEAR, 0);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999); //毫秒
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }

    public static DateTimeFormatter getFormatter(String pattern) {
        return DateTimeFormatter.ofPattern(pattern);
    }


    /**
     * 获取当前时间，yyyy-MM-dd HH:mm:ss
     */
    public static String getYmdHms() {
        DateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATETIME);
        return df.format(new Date());
    }

    public static String getNowByYmdHms() {
        DateFormat df = new SimpleDateFormat(DEFAULT_FORMAT);
        return df.format(new Date());
    }

    /**
     * 时间格式化，yyyy-MM-dd HH:mm:ss
     */
    public static String getYmdHms(Date date) {
        DateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATETIME);
        return df.format(date);
    }



    /**
     * 时间格式化，yyyy-MM-dd HH:mm:ss
     */
    public static Date getYmdHms(String date) {
        try {
            return new SimpleDateFormat(DEFAULT_FORMAT_DATETIME).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取当前日期，yyyy-MM-dd
     */
    public static String getYmd() {
        DateFormat df = new SimpleDateFormat(DEFAULT_FORMAT_DATE);
        return df.format(new Date());
    }

    /**
     * 日期格式化
     */
    public static String getFormatDate(Date date, String pattern) {
        DateFormat df = new SimpleDateFormat(pattern);
        return df.format(date);
    }

    /**
     * 日期格式化，yyyy-MM-dd
     */
    public static Date getYmd(String date) {
        try {
            return new SimpleDateFormat(DEFAULT_FORMAT_DATE).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *  按指定的格式，转换字符串为日期
     * @param date
     * @param pattern
     * @return
     */
    public static Date getDateByFormat(String date, String pattern){
        try {
            return new SimpleDateFormat(pattern).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    //同比时间求值方法
    public static Map<String,Date> getOneYearAgo(Date startTime, Date endTime) {

        // 计算一年前的当前日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        calendar.add(Calendar.YEAR, -1);
        Date oneYearAgo = calendar.getTime();

        // 计算一年前的开始时间和结束时间
        calendar.setTime(startTime);
        calendar.add(Calendar.YEAR, -1);
        Date oneYearAgoStartTime = calendar.getTime();
        calendar.setTime(endTime);
        calendar.add(Calendar.YEAR, -1);
        Date oneYearAgoEndTime = calendar.getTime();

        Map<String,Date> map=new HashMap<String,Date>();
        //一年前的开始时间
        map.put("oneYearAgoStartTime", oneYearAgoStartTime);
        //一年前的结束时间
        map.put("oneYearAgoEndTime", oneYearAgoEndTime);
        return map;
    }


    //求环比时间方法  环比的截止时间是本期起始时间的前一天
    public static Map<String, Date> getPreviousPeriod(Date startTime, Date endTime) {
        // 计算前一个周期的截止时间 = 本期起始时间的前一天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date previousPeriodEndTime = calendar.getTime();

        // 计算时间间隔
        long interval = endTime.getTime() - startTime.getTime();
        // 前一个周期的起始时间 = 截止时间 - 时间间隔
        Date previousPeriodStartTime = new Date(previousPeriodEndTime.getTime() - interval);
        // 创建Map对象存储结果
        Map<String, Date> map = new HashMap<>();
        // 将前一个周期的开始时间和结束时间放入Map中
        map.put("previousPeriodStartTime", previousPeriodStartTime);
        map.put("previousPeriodEndTime", previousPeriodEndTime);
        // 返回Map对象
        return map;
    }


}
